﻿using AutoMapper;
using Hotel.Common;
using Hotel.Domain;
using Hotel.IRepository;
using Hotel.IServices;
using Hotel.IServices.RequestDTO;
using Hotel.IServices.ResponseDTO;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hotel.Services
{
    public class RBACServices: IRBACServices
    {
        private readonly IMapper mapper;
        //用户名
        private readonly IBaseRepository<User>  userRepository;
        //用户角色
        private readonly IBaseRepository<UserRoleInfo>  userroleRepository;
        //角色
        private readonly IBaseRepository<RoleInfo>  roleinfoRepository;
        private readonly IBaseRepository<Permission>  permissionRepository;
        private readonly IBaseRepository<RolePermisstionInfo>  rolepermissionRepository;
        private readonly IRBACRepository rbacServices;
        private readonly ILogger<RBACServices> logger;

        public RBACServices(IMapper mapper, IBaseRepository<User> userRepository, IBaseRepository<UserRoleInfo> userroleRepository, IBaseRepository<RoleInfo> roleinfoRepository, IBaseRepository<Permission> permissionRepository, IBaseRepository<RolePermisstionInfo> rolepermissionRepository, IRBACRepository rbacServices, ILogger<RBACServices> logger)
        {
            this.mapper = mapper;
            this.userRepository = userRepository;
            this.userroleRepository = userroleRepository;
            this.roleinfoRepository = roleinfoRepository;
            this.permissionRepository = permissionRepository;
            this.rolepermissionRepository = rolepermissionRepository;
            this.rbacServices = rbacServices;
            this.logger = logger;
        }


        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> RegisterAsync(RegisterAsyncReqDto dto)
        {
            try
            {
                var result = new ApiResult<bool>("注册失败");

                var data = mapper.Map<User>(dto);
           

                List<UserRoleInfo> list = new List<UserRoleInfo>();
                foreach (var item in dto.RoleIds)
                {
                    list.Add(new UserRoleInfo(){ UserId = data.UserId,RoleId = (int)item });
                }
                var res = await rbacServices.RegisterAsync(data,list);
                if (res) result.Success();
                return result;
            }
            catch (Exception)
            {

                throw;
            }
        }



        /// <summary>
        /// 获取角色下拉框
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<List<ShowRoleAsyncReqDto>>> ShowRoleAsync()
        {
            var  result= new ApiResult<List<ShowRoleAsyncReqDto>>("查询失败");

            var data=await roleinfoRepository.GetAllAsync();
            var res = mapper.Map<List<ShowRoleAsyncReqDto>>(data);
            if (res != null) result.Success(res);
            return result;
        }

        /// <summary>
        /// 显示用户列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult<PagingResult<IList<ShowUserAsyncReqDto>>>> ShowUserAsync(UserAsyncPageReqDto dto)
        {
            var result=new ApiResult<PagingResult<IList<ShowUserAsyncReqDto>>>("显示失败");
          var list=  await userRepository.GetAllAsync();
            if (!string.IsNullOrEmpty(dto.UserName)) {
              
                list=list.Where(p=>p.UserName.Contains(dto.UserName)).ToList();
            }

            var TotalCount=list.Count();
            var PageCount = (int)Math.Ceiling(TotalCount * 1.0 / dto.PageSize);
            var data = list.OrderBy(p => p.UserId).Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToList();
            var query = mapper.Map<IList<ShowUserAsyncReqDto>>(data);

            foreach (var item in query) {
                var roleids=(await userroleRepository.GetAllAsync(p=>p.UserId==item.UserId)).Select(p=>p.RoleId).ToList();
                var rolenames=(await roleinfoRepository.GetAllAsync(p=> roleids.Contains(p.RoleId))).Select(p=>p.RoleName).ToList();
                item.RoleIds = rolenames;
            }
            var page = new PagingResult<IList<ShowUserAsyncReqDto>>();
            page.totalPage = PageCount;
            page.totalCount= TotalCount;
            page.data = query;

           result.Success(page);

            return result;

        }

        /// <summary>
        /// 用户查询
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public async Task<ApiResult<GetUserInfoAsyncReqDto>> GetUserInfoAsync(int userid)
        {
            var result = new ApiResult<GetUserInfoAsyncReqDto>("查询失败");
            var info = await userRepository.GetAsync(p => p.UserId ==userid);
            if (info != null && info.UserId > 0)
            {
                //映射
                var data = mapper.Map<GetUserInfoAsyncReqDto>(info);

                //查询角色
                var roleids = (await userroleRepository.GetAllAsync(p => p.UserId == userid)).Select(p => p.RoleId).ToList();
                data.Roles = roleids;
                result.Success(data);
            }
            return result;
        }

        /// <summary>
        /// 用户修改
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> UpDateUserInfoRegisterAsync(UpDateUserInfoRegisterAsyncReqDto dto)
        {
            try
            {
                var result = new ApiResult<bool>("注册失败");

                //先查询
             var info=   await userRepository.GetAsync(p => p.UserId == dto.UserId);

                //映射
                var data = mapper.Map(dto,info);


                
                List<UserRoleInfo> list = new List<UserRoleInfo>();
                foreach (var item in dto.RoleIds)
                {
                    list.Add(new UserRoleInfo() { UserId = data.UserId, RoleId = (int)item });
                }
                var res = await rbacServices.UpDateUserInfoAsync(data, list);
                if (res) result.Success();
                return result;
            }
            catch (Exception)
            {

                throw;
            }
        }



        /// <summary>
        /// 添加角色权限
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddRoleAsync(AddRoleAsyncReqDto dto)
        {
            try
            {
                var result = new ApiResult("添加失败");

                var data=mapper.Map<RoleInfo>(dto);
                List<RolePermisstionInfo> list= new List<RolePermisstionInfo>();

                foreach (var item in dto.PerIds)
                {
                    list.Add(new RolePermisstionInfo() { RoleId = 0, PermissionId = item });

                }
                var res = await rbacServices.AddRoleAsync(data, list);
                if (res) result.Success();
                return result;
            }
            catch (Exception)
            {

                throw;
            }

        }


        /// <summary>
        /// 获取权限列表
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<List<TreeReqDto>>> GetPermissionListAsync()
        {
            try
            {
                var result=new ApiResult<List<TreeReqDto>>("获取失败");
                var query=await permissionRepository.GetAllAsync();

                //过滤一级权限
                var ones=query.Where(p=>p.ParnentId==0).ToList();

                var list = new List<TreeReqDto>();

                //循环
                foreach (var item in ones)
                {
                    //获取一级权限
                    var tree = new TreeReqDto() { Id = item.PermissionId, label = item.PermissionTitle };
                    //获取二级权限
                    var twos= query.Where(p=>p.ParnentId==item.PermissionId).ToList();

                    foreach (var sub in twos)
                    {
                        var subtwo=new TreeReqDto() { Id = sub.PermissionId, label = sub.PermissionTitle };
                        
                        tree.children.Add(subtwo);
                    }
                    list.Add(tree);
                }

                result.Success(list);
              //  var data=mapper.Map<List<TreeReqDto>>(query);
                return result; 
            }
            catch (Exception)
            {

                throw;
            }
        }


        /// <summary>
        /// 显示角色权限列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult<PagingResult<IList<ShowRolePermssionAsyncReqDto>>>> ShowRolePermssionAsync(ShowRolePermssionAsyncPageReqDto dto)
        {
            try
            {
                var result=new ApiResult<PagingResult<IList<ShowRolePermssionAsyncReqDto>>>("显示失败");

                var list=await rolepermissionRepository.GetAllAsync();

                var TotalCount = list.Count();
                var PageCount = (int)Math.Ceiling(TotalCount * 1.0 / dto.PageSize);
                list=list.OrderBy(p=>p.RoleId).Skip((dto.PageIndex-1)*dto.PageSize).Take(dto.PageSize).ToList();

                var data = mapper.Map<IList<ShowRolePermssionAsyncReqDto>>(list);

                foreach (var item in data) { 
                   var permssionId=(await rolepermissionRepository.GetAllAsync(p=>p.RoleId==item.RoleId)).Select(p=>p.PermissionId).ToList();

                    var permissonName = (await permissionRepository.GetAllAsync(p => permssionId.Contains(p.ParnentId))).Select(p => p.PermissionName).ToList();
                }
                return result;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 获取权限树状图
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>

        public async Task<ApiResult<List<GetMenuListYserIdAsyncReqDto>>> GetMenuListYserIdAsync(int userid) 
        {
            try
            {
                var result= new ApiResult<List<GetMenuListYserIdAsyncReqDto>>("获取菜单失败");

                //根据用户编号查询对应的角色编号
                var RoleIds = (await  userroleRepository.GetAllAsync(p=>p.UserId==userid)).Select(p=>p.RoleId).ToList();

                //根据角色编号查询对应的权限编号并去重
                var PermissionIds = (await rolepermissionRepository.GetAllAsync(p=> RoleIds.Contains(p.RoleId))).Select(p=>p.PermissionId).Distinct().ToList();

                //根据权限编号查询对应的权限信息
                var perIds = await permissionRepository.GetAllAsync(p => PermissionIds.Contains(p.PermissionId));

                //查询对应的父级ID
                var perParents = perIds.Select(p=>p.ParnentId).ToList();

                //根据父级ID查询一级菜单
                var PermssionParents =await permissionRepository.GetAllAsync(p => perParents.Contains(p.PermissionId));


                List<GetMenuListYserIdAsyncReqDto> list= new List<GetMenuListYserIdAsyncReqDto>();

                //从一级菜单开始循环
                foreach (var item in PermssionParents)
                {
                    var menu=new GetMenuListYserIdAsyncReqDto() { PermissionId=item.PermissionId,PermissionName=item.PermissionName,PermissionAction=item.PermissionAction};

                    var subs = perIds.Where(p => p.ParnentId == item.PermissionId).ToList();
                    foreach (var sub in subs)
                    {
                        menu.Children.Add(new GetMenuListYserIdAsyncReqDto() { PermissionId = item.PermissionId, PermissionName = item.PermissionName, PermissionAction = item.PermissionAction });
                    }
                    list.Add(menu);
                }

                result.Success(list);
                return result;


            }
            catch (Exception)
            {

                throw;
            }
        
        }
    }
}
